package cn.xinfei.xdecision.common.service.script.groovy;

import cn.xinfei.xdecision.common.model.component.scriptrule.RuleTestData;
import cn.xinfei.xdecision.common.utils.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.PropertyPlaceholderHelper;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static cn.xinfei.xdecision.common.utils.exception.enums.ErrorCodeEnum.SERVER_ERROR;

@Slf4j
@Component
public class ScriptTemplate {

    protected static StringBuilder template = new StringBuilder();

    @PostConstruct
    public void init() {
        ClassLoader classLoader = this.getClass().getClassLoader();
        // 获取配置路径
        InputStream is = classLoader.getResourceAsStream("script-template/groovy-template");
        if (Objects.isNull(is)) {
            log.warn("script-template/groovy-template 文件不存在");
            return;
        }
        // 转换流
        try {
            StringWriter writer = new StringWriter();
            IOUtils.copy(is, writer, StandardCharsets.UTF_8.name());
            template.append(writer);
        } catch (IOException e) {
            throw new ApiException(SERVER_ERROR);
        }
    }

    public static Object scriptExecution(String script, Map<String, RuleTestData> varCodeAndValMap) {
        return ScriptUtils.executeScriptBinding(replaceGroovyScript(script), varCodeAndValMap);
    }

    public static String replaceGroovyScript(String script) {
        if (StringUtils.isEmpty(template)) {
            throw new ApiException(SERVER_ERROR);
        }
        Map<String, String> map = new HashMap<>();
        map.put("CUSTOMER_SCRIPT_AREA", script);
        PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${", "}");
        return propertyPlaceholderHelper.replacePlaceholders(template.toString(), map::get);
    }

}
